#ifndef ELK_DOWNLOAD_MANAGER_H
#define ELK_DOWNLOAD_MANAGER_H

#include <QFile>
#include <QNetworkReply>
#include <QNetworkAccessManager>

class ElkDownloadTask : public QObject
{
    Q_OBJECT

public:
    explicit ElkDownloadTask(QObject *parent=nullptr);
    ~ElkDownloadTask();

    void start(const QString &url,
               const QString &fileName,
               QNetworkAccessManager *network);

    void abort();
    void retry();
    void clear();

    QString url() const {return url_;}
    QString fileName() const {return fileName_;}

signals:
    void finished();
    void interrupted();
    void downloadProgress(qint64, qint64, qint64);

    void urlChanged(const QString &url);
    void fileError(QFile::FileError, const QString &);
    void replyError(QNetworkReply::NetworkError, const QString &);

private:
    bool fileOpen();
    bool fileWrite();
    bool fileRename();

    void clearFile();
    void abortReply();

    bool complete();
    void resetRequest();

private slots:
    void metaDataChanged();

    void replyFinished();
    void replyReadyRead();
    void replyRedirected(const QUrl &url);
    void replyDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);

    void replyDestroyed(QObject *obj);
    void networkDestroyed(QObject *obj);

private:
    QString url_;
    QString fileName_;

    qint64 bytesTotal_ = 0;
    qint64 bytesReceived_ = 0;
    qint64 bytesFileSize_ = 0;

    QFile file_;
    QNetworkReply *reply_ = nullptr;
    QNetworkAccessManager *network_ = nullptr;
};

class ElkDownloadManager : public QObject
{
    Q_OBJECT

public:
    explicit ElkDownloadManager(QObject *parent=nullptr);
    ~ElkDownloadManager();

    ElkDownloadTask *createDownloadTask(const QString &url,
                                        const QString &fileName);
    void deleteDownloadTask(ElkDownloadTask *task);

    QList<ElkDownloadTask *> allDownloadTasks() const {return tasks_;}

private slots:
    void taskDestroyed(QObject *obj);
    void replyFinished(QNetworkReply *reply);

private:
    QList<ElkDownloadTask *> tasks_;
    QNetworkAccessManager *network_ = nullptr;
};

#endif // ELK_DOWNLOAD_MANAGER_H
